# 路径索引
import json
import os

from lxml import etree


class Category:
    home = 'home.html'
    gaishu = 'gaishu.html'
    cause = 'cause.html'
    prevent = 'prevent.html'
    neopathy = 'neopathy.html'
    symptom = 'symptom.html'
    inspect = 'inspect.html'
    diagnosis = 'diagnosis.html'
    treat = 'treat.html'
    nursing = 'nursing.html'
    food = 'food.html'
    drug = 'drug.html'


class Extractor(object):
    def __init__(self, gaisu_path, cause_path, prevent_path, neopathy_path, symptom_path, inspect_path, diagnosis_path,
                 treat_path, nursing_path, food_path, save_path):
        self.gaisu_path = gaisu_path
        self.cause_path = cause_path
        self.prevent_path = prevent_path
        self.neopathy_path = neopathy_path
        self.symptom_path = symptom_path
        self.inspect_path = inspect_path
        self.diagnois_path = diagnosis_path
        self.treat_path = treat_path
        self.nursing_path = nursing_path
        self.food_path = food_path
        self.save_path = save_path

    def read_content(self, path):
        with open(path, mode='r', encoding='gb18030') as f:
            content = f.read()
        return etree.HTML(content)

    def extract_from_gaishu(self, path):
        gaishu_dict = {'title': '疾病简介', 'content': []}
        content = self.read_content(path)
        intro = content.xpath('//div[@class="jib-articl-con jib-lh-articl"]/p/text()')

        if intro:
            gaishu_dict['content'].append({'title': '简介', 'text': intro[0].strip()})

        titles = content.xpath('//div[@class="mt20 articl-know"]/p/span[1]/text()')
        # print(titles)
        texts = content.xpath('//div[@class="mt20 articl-know"]/p/span[2]')
        re_texts = []
        for text in texts:
            re_texts.append('，'.join(text.xpath('string(.)').strip().split()))
        # print(re_texts)

        for title, text in zip(titles, re_texts):
            gaishu_dict['content'].append({'title': title, 'text': text})
        # print(gaishu_dict)
        return gaishu_dict

    def extract_from_other(self, path):
        content = self.read_content(path)
        # p_list = content.xpath('//div[@class="jib-articl fr f14 jib-lh-articl"]/p') or content.xpath('//div[@class=" jib-articl fr f14 jib-lh-articl"]/p') or content.xpath('//div[@class="jib-lh-articl"]/p')
        p_list = content.xpath(
            '//div[contains(@class, "jib-lh-articl")]/p | //div[contains(@class, "jib-lh-articl")]/h3 | //div[contains(@class, "jib-lh-articl")]/div[not(@class)] ')

        p_list0 = self.remove_blank_p(p_list)
        p_list1 = []
        for p in p_list0:
            if not ''.join(p.xpath('text()')).strip() and p.xpath('strong'):
                p_list1.append({'content': p.xpath('string(.)').strip(), 'type': 2})
            # h3 肿瘤因素 span（74%） span h3
            elif p.tag == 'h3':
                p_list1.append({'content': p.xpath('string(.)').strip(), 'type': 2})

            else:
                p_list1.append({'content': p.xpath('string(.)').strip(), 'type': 4})

        p_list2 = self.add_id(p_list1)
        p_list3 = self.add_parent_id(p_list2)
        inter_content = self.get_json_tree(p_list3, -1)

        final_content_dict = {}
        if path == self.cause_path:
            final_content_dict = {'title': '病因', 'content': inter_content}
        elif path == self.prevent_path:
            final_content_dict = {'title': '预防', 'content': inter_content}
        elif path == self.neopathy_path:
            final_content_dict = {'title': '并发症', 'content': inter_content}
        elif path == self.symptom_path:
            final_content_dict = {'title': '症状', 'content': inter_content}
        elif path == self.inspect_path:
            final_content_dict = {'title': '检查', 'content': inter_content}
        elif path == self.diagnois_path:
            final_content_dict = {'title': '诊断鉴别', 'content': inter_content}
        elif path == self.treat_path:
            final_content_dict = {'title': '治疗', 'content': inter_content}
        elif path == self.nursing_path:
            final_content_dict = {'title': '护理', 'content': inter_content}
        return final_content_dict

    def remove_blank_p(self, l):
        """删除空内容的p标签"""
        l2 = []
        for p in l:
            if p.xpath('string(.)').strip():
                l2.append(p)
        return l2

    def add_id(self, l):
        l2 = []
        for index, p in enumerate(l):
            p['id'] = index
            l2.append(p)
        return l2

    def add_parent_id(self, l):
        l2 = []
        for index, p in enumerate(l):
            for i, p2 in enumerate(l[index::-1]):
                if p2['type'] < p['type']:
                    p['parent_id'] = p2['id']
                    break
            if 'parent_id' not in p:
                p['parent_id'] = -1
            l2.append(p)
        return l2

    def get_json_tree(self, data, parent_id):
        content = []
        for item in data:
            if item['parent_id'] == parent_id:
                if item['type'] == 4:
                    new_node = {'text': item['content']}
                else:
                    new_node = {'title': item['content'], 'content': self.get_json_tree(data, item['id'])}
                content.append(new_node)
        return content

    def extract_from_food(self, path):
        content = self.read_content(path)
        try:
            text1 = content.xpath('//div[contains(@class, "diet-item none clearfix")]/div[1]/div[2]/text()')[0].strip()
        except:
            text1 = ''

        try:
            text2 = content.xpath('//div[contains(@class, "diet-item none")][2]/div[1]/div[2]/text()')[0].strip()
        except:
            text2 = ''

        diet_dict = {'title': "饮食保健", 'content': [{'title': '宜', 'text': text1}, {'title': '忌', 'text': text2}]}
        return diet_dict

    def run(self):
        # 获得疾病名字
        content = self.read_content(self.gaisu_path)
        name = content.xpath('//div[contains(@class, "jb-name")]/text()')[0]
        file_name = self.gaisu_path.split('\\')[-2].split('.')[0]
        # print(file_name)

        final_dict = {'title': name, 'content': []}

        gaisu = self.extract_from_gaishu(self.gaisu_path)
        cause = self.extract_from_other(self.cause_path)
        prevent = self.extract_from_other(self.prevent_path)
        neopathy = self.extract_from_other(self.neopathy_path)
        symptom = self.extract_from_other(self.symptom_path)
        inspect = self.extract_from_other(self.inspect_path)
        diagnois = self.extract_from_other(self.diagnois_path)
        treat = self.extract_from_other(self.treat_path)
        nursing = self.extract_from_other(self.nursing_path)
        food = self.extract_from_food(self.food_path)

        final_dict['content'].extend(
            [gaisu, cause, prevent, neopathy, symptom, inspect, diagnois, treat, nursing, food])
        self.write2json(final_dict, self.save_path, file_name)

    def write2json(self, new_content, path, file_name):
        with open(os.path.join(self.save_path, file_name + '.json'), mode='w', encoding='utf-8') as f:
            json.dump(new_content, f, ensure_ascii=False)


def main():
    path = 'D:/PycharmProjects/xywy_data'
    save_path = 'D:/PycharmProjects/xywy_data/json_data'

    with open('urls.txt', mode='r', encoding='utf-8') as f:
        url_list = f.read().splitlines()
    for i in range(0, len(url_list)):
        print(i + 1)
        dir_name = url_list[i].split('/')[-1]
        gaisu_path = os.path.join(path, dir_name, Category.gaishu)
        cause_path = os.path.join(path, dir_name, Category.cause)
        prevent_path = os.path.join(path, dir_name, Category.prevent)
        neopathy_path = os.path.join(path, dir_name, Category.neopathy)
        symptom_path = os.path.join(path, dir_name, Category.symptom)
        inspect_path = os.path.join(path, dir_name, Category.inspect)
        diagnosis_path = os.path.join(path, dir_name, Category.diagnosis)
        treat_path = os.path.join(path, dir_name, Category.treat)
        nursing_path = os.path.join(path, dir_name, Category.nursing)
        food_path = os.path.join(path, dir_name, Category.food)

        extract = Extractor(gaisu_path, cause_path, prevent_path, neopathy_path, symptom_path, inspect_path,
                            diagnosis_path,
                            treat_path, nursing_path, food_path, save_path)
        extract.run()
        break


if __name__ == '__main__':
    main()
